#ifndef DEF_GAME_OBJECT
#define DEF_GAME_OBJECT

#include <vector>
#include <typeinfo>
#include <iostream>

#include "../Components/IncludeComponents.h"


class GameObject
{
public:
	
	GameObject();
	GameObject(std::string name);
	virtual ~GameObject();

	void Update(float time);
	void Render(Matrix4 view, Matrix4 proj);

	//Statics
	static void UpdateScene(float time);
	static void RenderScene(Matrix4 view, Matrix4 proj);
	static void DeleteScene();

	//Getter & Setter
	std::string GetName() { return _name; }
	void SetName(std::string name) {_name = name;}
	Transform* GetTransform() {return _transform;}
	void SetParent(GameObject* parent) { _parent = parent; _parent->_childs.push_back(this); }

	//Check if a Component is present
	template <class T> bool HasComponent() 
	{ 
		for(std::vector<Component*>::iterator it = _components.begin(); it != _components.end(); ++it)
		{
			T* comp = dynamic_cast<T*>(*it);
			if(comp != NULL)
				return true;
		}

		return false; 
	}

	//Get a component
	template <class T> T* GetComponent()
	{

		for(std::vector<Component*>::iterator it = _components.begin(); it != _components.end(); ++it)
		{
			T* comp = dynamic_cast<T*>(*it);
			if(comp != NULL)
				return comp;
		}

		return NULL;
	}
	
	//Add a Component
	template <class T> void AddComponent(T* t) 
	{ 
		_components.push_back(t);
		t->SetGameObject(this);
	}

	//Remove a Component
	template <class T> void RemoveComponent(T* t) 
	{ 
		for(std::vector<Component*>::iterator it = _components.begin(); it != _components.end(); ++it)
		{
			T* comp = dynamic_cast<T*>(*it);
			if(comp != NULL)
			{
				if(_components.size() > 1)
					_components.swap(it, --_components.end());

				_components.pop_back();
			}
		}
	}

	
protected:
	static std::vector<GameObject*> _gameObjectsInScene;

	std::vector<Component*> _components;
	std::string _name;
	Transform* _transform;
	GameObject* _parent;
	std::vector<GameObject*> _childs;
};


#endif //DEF_GAME_OBJECT





